package com.company.genealogy.common.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 * 
 * 提供Redis操作的工具方法，主要用于token存储和管理。
 * 支持访问token和刷新token的存储、获取、删除等操作。
 * 
 * @author chenzhixiang
 */
@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 访问token的Redis key前缀
     */
    private static final String ACCESS_TOKEN_PREFIX = "access_token:";

    /**
     * 刷新token的Redis key前缀
     */
    private static final String REFRESH_TOKEN_PREFIX = "refresh_token:";

    /**
     * 用户黑名单的Redis key前缀
     */
    private static final String USER_BLACKLIST_PREFIX = "user_blacklist:";

    /**
     * 存储访问token
     * 
     * @param userId 用户ID
     * @param token 访问token
     * @param expiration 过期时间（秒）
     */
    public void storeAccessToken(Long userId, String token, long expiration) {
        String key = ACCESS_TOKEN_PREFIX + userId;
        redisTemplate.opsForValue().set(key, token, expiration, TimeUnit.SECONDS);
    }

    /**
     * 存储刷新token
     * 
     * @param userId 用户ID
     * @param token 刷新token
     * @param expiration 过期时间（秒）
     */
    public void storeRefreshToken(Long userId, String token, long expiration) {
        String key = REFRESH_TOKEN_PREFIX + userId;
        redisTemplate.opsForValue().set(key, token, expiration, TimeUnit.SECONDS);
    }

    /**
     * 获取访问token
     * 
     * @param userId 用户ID
     * @return 访问token，如果不存在或已过期则返回null
     */
    public String getAccessToken(Long userId) {
        String key = ACCESS_TOKEN_PREFIX + userId;
        Object value = redisTemplate.opsForValue().get(key);
        return value != null ? value.toString() : null;
    }

    /**
     * 获取刷新token
     * 
     * @param userId 用户ID
     * @return 刷新token，如果不存在或已过期则返回null
     */
    public String getRefreshToken(Long userId) {
        String key = REFRESH_TOKEN_PREFIX + userId;
        Object value = redisTemplate.opsForValue().get(key);
        return value != null ? value.toString() : null;
    }

    /**
     * 删除访问token
     * 
     * @param userId 用户ID
     */
    public void deleteAccessToken(Long userId) {
        String key = ACCESS_TOKEN_PREFIX + userId;
        redisTemplate.delete(key);
    }

    /**
     * 删除刷新token
     * 
     * @param userId 用户ID
     */
    public void deleteRefreshToken(Long userId) {
        String key = REFRESH_TOKEN_PREFIX + userId;
        redisTemplate.delete(key);
    }

    /**
     * 删除用户的所有token
     * 
     * @param userId 用户ID
     */
    public void deleteAllTokens(Long userId) {
        deleteAccessToken(userId);
        deleteRefreshToken(userId);
    }

    /**
     * 检查访问token是否存在
     * 
     * @param userId 用户ID
     * @return true-存在，false-不存在
     */
    public boolean hasAccessToken(Long userId) {
        String key = ACCESS_TOKEN_PREFIX + userId;
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 检查刷新token是否存在
     * 
     * @param userId 用户ID
     * @return true-存在，false-不存在
     */
    public boolean hasRefreshToken(Long userId) {
        String key = REFRESH_TOKEN_PREFIX + userId;
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 将用户加入黑名单
     * 
     * @param userId 用户ID
     * @param expiration 黑名单过期时间（秒）
     */
    public void addToBlacklist(Long userId, long expiration) {
        String key = USER_BLACKLIST_PREFIX + userId;
        redisTemplate.opsForValue().set(key, "1", expiration, TimeUnit.SECONDS);
    }

    /**
     * 检查用户是否在黑名单中
     * 
     * @param userId 用户ID
     * @return true-在黑名单中，false-不在黑名单中
     */
    public boolean isInBlacklist(Long userId) {
        String key = USER_BLACKLIST_PREFIX + userId;
        return Boolean.TRUE.equals(redisTemplate.hasKey(key));
    }

    /**
     * 从黑名单中移除用户
     * 
     * @param userId 用户ID
     */
    public void removeFromBlacklist(Long userId) {
        String key = USER_BLACKLIST_PREFIX + userId;
        redisTemplate.delete(key);
    }

    /**
     * 获取访问token的剩余过期时间
     * 
     * @param userId 用户ID
     * @return 剩余过期时间（秒），-1表示不存在，-2表示没有过期时间
     */
    public long getAccessTokenExpiration(Long userId) {
        String key = ACCESS_TOKEN_PREFIX + userId;
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 获取刷新token的剩余过期时间
     * 
     * @param userId 用户ID
     * @return 剩余过期时间（秒），-1表示不存在，-2表示没有过期时间
     */
    public long getRefreshTokenExpiration(Long userId) {
        String key = REFRESH_TOKEN_PREFIX + userId;
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }
} 